mod handler;
mod model;
mod pkg;
mod router;
mod utils;
use crate::handler::login;
use crate::router::router::{
    control_core_router, device_router, modules_router, sd_router, topic_router, user_router,
};

use actix_web::{web, App, HttpServer};

use crate::router::middleware;
use env_logger::Env;
use reqwest::StatusCode;
use tokio::task;
use tokio::time::{sleep, Duration};

#[tokio::main]
async fn main() -> Result<(), sqlx::Error> {
    // 设置环境
    // env::set_var("RUST_LOG", "sqlx=debug");
    // env_logger::init();

    // 输出 api 地址
    println!("start api http://127.0.0.1:7001");

    // 日志
    env_logger::init_from_env(Env::default().default_filter_or("info"));

    // 初始化数据库
    model::db::init_db_pool().await?;

    // 系统自检
    task::spawn(async {
        let a1 = ping_server().await;
        match a1 {
            Ok(()) => println!("The router has been deployed successfully"),
            Err(e) => println!(
                "The router has no response, or it might took too long to start up. {:?}",
                e
            ),
        }
    });

    HttpServer::new(|| {
        App::new()
            .route("/v1/admin/login", web::post().to(login::admin_login))
            .service(web::scope("/v1/sd_admin").configure(sd_router))
            .service(
                web::scope("/v1/admin")
                    .wrap(middleware::auth::Auth)
                    .configure(user_router)
                    .configure(topic_router)
                    .configure(device_router)
                    .configure(control_core_router)
                    .configure(modules_router),
            )
    })
    .bind(("0.0.0.0", 7001))?
    .run()
    .await
    .unwrap();
    Ok(())
}

async fn ping_server() -> Result<(), StatusCode> {
    for _ in 0..10 {
        let resp = reqwest::get("http://127.0.0.1:7001/v1/sd_admin/sd/health_check").await;
        match resp {
            Ok(i) => {
                if i.status() == 200 {
                    return Ok(());
                }
            }
            Err(e) => {
                println!("Error: {:?}", e);
            }
        }
        println!("Waiting for the router, retry in 1 second.");
        sleep(Duration::from_secs(1)).await;
    }

    Err(StatusCode::INTERNAL_SERVER_ERROR)
}
